﻿/*
 *********************************************************************
 *    Management Extensions for Windows Windows Server AppFabric     *
 *********************************************************************
 *    Author    : Fatih Boy [fatih@enterprisecoding.com]             *
 *    Web site  : http://www.enterprisecoding.com                    *
 *********************************************************************
 *    License   : GNU Library General Public License (LGPL)          * 
 *********************************************************************
 */

using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using Microsoft.ApplicationServer.Caching;
using Microsoft.Web.Management.Client.Win32;

using Com.Enterprisecoding.AppFabric.Extensions.Client.Resources.Cache;

namespace Com.Enterprisecoding.AppFabric.Extensions.Client.Pages.Cache.ConfigBackup {
    internal sealed class ConfigBackupPage : ModulePage {
        #region Data Members
        private const int SERIALIZATION_BUFFER_SIZE = 262140;

        private ConfigBackupServiceProxy configBackupServiceProxy;

        private Label restoreFileNameLabel;
        private TextBox restoreFileName;
        private Button restoreBrowse;
        private Button restore;
        private OpenFileDialog openFileDialog;
        private Button backup;
        private GroupBox groupBox1;
        private Label restoreDescription;
        private PictureBox pictureBox1;
        private GroupBox groupBox2;
        private Label backupDescription;
        private PictureBox pictureBox2;
        private TextBox backupFileName;
        private Label backupFileNameLabel;
        private Button backupBrowse;
        private SaveFileDialog saveFileDialog;
        #endregion

        public ConfigBackupPage() {
            InitializeComponent();

            restoreFileNameLabel.Text = Resources.Cache.ConfigBackupPage.FileNameLabel;
            backupFileNameLabel.Text = Resources.Cache.ConfigBackupPage.FileNameLabel;
            restore.Text = Resources.Cache.ConfigBackupPage.Restore;
            backup.Text = Resources.Cache.ConfigBackupPage.Backup;
            restoreBrowse.Text = Resources.Cache.ConfigBackupPage.Browse;
            backupBrowse.Text = Resources.Cache.ConfigBackupPage.Browse;
            restoreDescription.Text = Resources.Cache.ConfigBackupPage.RestoreDescription;
            backupDescription.Text = Resources.Cache.ConfigBackupPage.BackupDescription;
        }

        protected override void OnActivated(bool initialActivation) {
            base.OnActivated(initialActivation);

            configBackupServiceProxy = (ConfigBackupServiceProxy)base.CreateProxy(typeof(ConfigBackupServiceProxy));
        }

        #region Backup Cache Cluster Config
        private void BackupCacheClusterConfig() {
            Enabled = false;
            base.StartAsyncTask(Resources.Cache.ConfigBackupPage.BackupCacheClusterConfigProgressText, OnBackupCacheClusterConfig, OnBackupCacheClusterConfigCompleted, null, backupFileName.Text);
        }

        private void OnBackupCacheClusterConfig(object sender, DoWorkEventArgs e) {
            var configExportInfo = configBackupServiceProxy.ExportCacheClusterConfig();

            try {
                long bytesRead = 0;
                using (var configFileStream = new FileStream((string)e.Argument, FileMode.Create)) {
                    bool flag;

                    do {
                        var configExport = configBackupServiceProxy.DownloadCacheClusterConfig(configExportInfo.ConfigFileGuid, bytesRead);
                        if (configExport != null) {
                            flag = configExport.Flag;
                            configFileStream.Write(configExport.ConfigFileContent, 0, configExport.ConfigFileContent.Length);
                            bytesRead += configExport.ConfigFileContent.Length;
                        }
                        else {
                            flag = true;
                        }
                    } while (!flag);
                }
            }
            finally {
                configBackupServiceProxy.ClearCacheClusterConfigExportFile(configExportInfo.ConfigFileGuid);
            }
        }

        private void OnBackupCacheClusterConfigCompleted(object sender, RunWorkerCompletedEventArgs e) {
            Enabled = true;
            var managementUIService = (IManagementUIService)base.GetService(typeof(IManagementUIService));

            if (e.Error != null) {
                if (e.Error.InnerException != null && e.Error.InnerException is DataCacheException) {
                    var innerEx = (DataCacheException)e.Error.InnerException;

                    managementUIService.ShowError(innerEx, Resources.Cache.ConfigBackupPage.BackupCacheClusterConfigExceptionMessage, Resources.Cache.ConfigBackupPage.BackupCacheClusterConfigExceptionCaption, false);
                    return;
                }
            }

            managementUIService.ShowMessage(Resources.Cache.ConfigBackupPage.BackupCompletedDialogMessage, Resources.Cache.ConfigBackupPage.BackupCompletedDialogCaption, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        #endregion

        #region Restore Cache Cluster Config
        private void RestoreCacheClusterConfig() {
            Enabled = false;
            base.StartAsyncTask(Resources.Cache.ConfigBackupPage.RestoreCacheClusterConfigProgressText, OnRestoreCacheClusterConfig, OnRestoreCacheClusterConfigCompleted, null, restoreFileName.Text);
        }

        private void OnRestoreCacheClusterConfig(object sender, DoWorkEventArgs e) {
            var configFileGuid = Guid.NewGuid();

            using (var configFileStream = File.OpenRead((string)e.Argument)) {
                byte[] buffer = new byte[SERIALIZATION_BUFFER_SIZE];
                while (configFileStream.Read(buffer, 0, SERIALIZATION_BUFFER_SIZE) > 0) {
                    configBackupServiceProxy.UploadCacheClusterConfig(configFileGuid, buffer);
                }
            }

            configBackupServiceProxy.ImportCacheClusterConfig(configFileGuid);
        }

        private void OnRestoreCacheClusterConfigCompleted(object sender, RunWorkerCompletedEventArgs e) {
            Enabled = true;
            var managementUIService = (IManagementUIService)base.GetService(typeof(IManagementUIService));

            if (e.Error != null) {
                if (e.Error.InnerException != null && e.Error.InnerException is DataCacheException) {
                    var innerEx = (DataCacheException)e.Error.InnerException;

                    managementUIService.ShowError(innerEx, Resources.Cache.ConfigBackupPage.RestoreCacheClusterConfigExceptionMessage, Resources.Cache.ConfigBackupPage.RestoreCacheClusterConfigExceptionCaption, false);
                    return;
                }
            }

            managementUIService.ShowMessage(Resources.Cache.ConfigBackupPage.RestoreCompletedDialogMessage, Resources.Cache.ConfigBackupPage.RestoreCompletedDialogCaption, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        #endregion

        private void InitializeComponent() {
            this.restoreFileNameLabel = new System.Windows.Forms.Label();
            this.restoreFileName = new System.Windows.Forms.TextBox();
            this.restoreBrowse = new System.Windows.Forms.Button();
            this.restore = new System.Windows.Forms.Button();
            this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
            this.backup = new System.Windows.Forms.Button();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.restoreDescription = new System.Windows.Forms.Label();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.backupDescription = new System.Windows.Forms.Label();
            this.backupFileName = new System.Windows.Forms.TextBox();
            this.backupFileNameLabel = new System.Windows.Forms.Label();
            this.backupBrowse = new System.Windows.Forms.Button();
            this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.pictureBox2 = new System.Windows.Forms.PictureBox();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
            this.SuspendLayout();
            // 
            // restoreFileNameLabel
            // 
            this.restoreFileNameLabel.AutoSize = true;
            this.restoreFileNameLabel.Location = new System.Drawing.Point(60, 47);
            this.restoreFileNameLabel.Name = "restoreFileNameLabel";
            this.restoreFileNameLabel.Size = new System.Drawing.Size(52, 13);
            this.restoreFileNameLabel.TabIndex = 0;
            this.restoreFileNameLabel.Text = "File name";
            // 
            // restoreFileName
            // 
            this.restoreFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.restoreFileName.Location = new System.Drawing.Point(122, 43);
            this.restoreFileName.Name = "restoreFileName";
            this.restoreFileName.Size = new System.Drawing.Size(75, 20);
            this.restoreFileName.TabIndex = 1;
            this.restoreFileName.TextChanged += new System.EventHandler(this.restoreFileName_TextChanged);
            // 
            // restoreBrowse
            // 
            this.restoreBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.restoreBrowse.Location = new System.Drawing.Point(200, 41);
            this.restoreBrowse.Name = "restoreBrowse";
            this.restoreBrowse.Size = new System.Drawing.Size(75, 23);
            this.restoreBrowse.TabIndex = 2;
            this.restoreBrowse.Text = "Browse";
            this.restoreBrowse.UseVisualStyleBackColor = true;
            this.restoreBrowse.Click += new System.EventHandler(this.browse_Click);
            // 
            // restore
            // 
            this.restore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.restore.Enabled = false;
            this.restore.Location = new System.Drawing.Point(281, 41);
            this.restore.Name = "restore";
            this.restore.Size = new System.Drawing.Size(75, 23);
            this.restore.TabIndex = 3;
            this.restore.Text = "&Restore";
            this.restore.UseVisualStyleBackColor = true;
            this.restore.Click += new System.EventHandler(this.restore_Click);
            // 
            // openFileDialog
            // 
            this.openFileDialog.DefaultExt = "xml";
            this.openFileDialog.FileName = "ClusterConfig.xml";
            // 
            // backup
            // 
            this.backup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.backup.Enabled = false;
            this.backup.Location = new System.Drawing.Point(281, 40);
            this.backup.Name = "backup";
            this.backup.Size = new System.Drawing.Size(75, 23);
            this.backup.TabIndex = 4;
            this.backup.Text = "&Backup";
            this.backup.UseVisualStyleBackColor = true;
            this.backup.Click += new System.EventHandler(this.backup_Click);
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox1.Controls.Add(this.restoreDescription);
            this.groupBox1.Controls.Add(this.restoreFileName);
            this.groupBox1.Controls.Add(this.pictureBox2);
            this.groupBox1.Controls.Add(this.restore);
            this.groupBox1.Controls.Add(this.restoreFileNameLabel);
            this.groupBox1.Controls.Add(this.restoreBrowse);
            this.groupBox1.Location = new System.Drawing.Point(12, 92);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(362, 74);
            this.groupBox1.TabIndex = 5;
            this.groupBox1.TabStop = false;
            // 
            // restoreDescription
            // 
            this.restoreDescription.AutoSize = true;
            this.restoreDescription.Location = new System.Drawing.Point(60, 16);
            this.restoreDescription.Name = "restoreDescription";
            this.restoreDescription.Size = new System.Drawing.Size(273, 13);
            this.restoreDescription.TabIndex = 4;
            this.restoreDescription.Text = "Please select a file to restore cache cluster configuration";
            // 
            // groupBox2
            // 
            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox2.Controls.Add(this.backupDescription);
            this.groupBox2.Controls.Add(this.pictureBox1);
            this.groupBox2.Controls.Add(this.backup);
            this.groupBox2.Controls.Add(this.backupFileName);
            this.groupBox2.Controls.Add(this.backupFileNameLabel);
            this.groupBox2.Controls.Add(this.backupBrowse);
            this.groupBox2.Location = new System.Drawing.Point(12, 12);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(362, 74);
            this.groupBox2.TabIndex = 6;
            this.groupBox2.TabStop = false;
            // 
            // backupDescription
            // 
            this.backupDescription.AutoSize = true;
            this.backupDescription.Location = new System.Drawing.Point(60, 16);
            this.backupDescription.Name = "backupDescription";
            this.backupDescription.Size = new System.Drawing.Size(301, 13);
            this.backupDescription.TabIndex = 4;
            this.backupDescription.Text = "Please select a location to backup cache cluster configuration";
            // 
            // backupFileName
            // 
            this.backupFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.backupFileName.Location = new System.Drawing.Point(122, 43);
            this.backupFileName.Name = "backupFileName";
            this.backupFileName.Size = new System.Drawing.Size(75, 20);
            this.backupFileName.TabIndex = 1;
            this.backupFileName.TextChanged += new System.EventHandler(this.backupFileName_TextChanged);
            // 
            // backupFileNameLabel
            // 
            this.backupFileNameLabel.AutoSize = true;
            this.backupFileNameLabel.Location = new System.Drawing.Point(60, 47);
            this.backupFileNameLabel.Name = "backupFileNameLabel";
            this.backupFileNameLabel.Size = new System.Drawing.Size(52, 13);
            this.backupFileNameLabel.TabIndex = 0;
            this.backupFileNameLabel.Text = "File name";
            // 
            // backupBrowse
            // 
            this.backupBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.backupBrowse.Location = new System.Drawing.Point(200, 41);
            this.backupBrowse.Name = "backupBrowse";
            this.backupBrowse.Size = new System.Drawing.Size(75, 23);
            this.backupBrowse.TabIndex = 2;
            this.backupBrowse.Text = "Browse";
            this.backupBrowse.UseVisualStyleBackColor = true;
            this.backupBrowse.Click += new System.EventHandler(this.backupBrowse_Click);
            // 
            // saveFileDialog
            // 
            this.saveFileDialog.DefaultExt = "xml";
            this.saveFileDialog.FileName = "ClusterConfig.xml";
            // 
            // pictureBox1
            // 
            this.pictureBox1.Image = global::Com.Enterprisecoding.AppFabric.Extensions.Client.Properties.Resources.Download_48;
            this.pictureBox1.Location = new System.Drawing.Point(6, 12);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(48, 48);
            this.pictureBox1.TabIndex = 3;
            this.pictureBox1.TabStop = false;
            // 
            // pictureBox2
            // 
            this.pictureBox2.Image = global::Com.Enterprisecoding.AppFabric.Extensions.Client.Properties.Resources.Upload_48;
            this.pictureBox2.Location = new System.Drawing.Point(6, 12);
            this.pictureBox2.Name = "pictureBox2";
            this.pictureBox2.Size = new System.Drawing.Size(48, 48);
            this.pictureBox2.TabIndex = 3;
            this.pictureBox2.TabStop = false;
            // 
            // ConfigBackupPage
            // 
            this.ClientSize = new System.Drawing.Size(454, 262);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.groupBox1);
            this.Name = "ConfigBackupPage";
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
            this.ResumeLayout(false);

        }

        private void browse_Click(object sender, EventArgs e) {
            if (openFileDialog.ShowDialog() == DialogResult.OK) {
                restoreFileName.Text = openFileDialog.FileName;
            }
        }

        private void restoreFileName_TextChanged(object sender, EventArgs e) {
            restore.Enabled = File.Exists(restoreFileName.Text);
        }

        private void restore_Click(object sender, EventArgs e) {
            RestoreCacheClusterConfig();
        }

        private void backup_Click(object sender, EventArgs e) {
            BackupCacheClusterConfig();
        }

        private void backupFileName_TextChanged(object sender, EventArgs e) {
            var fileInfo = new FileInfo(backupFileName.Text);
            backup.Enabled = !string.IsNullOrEmpty(backupFileName.Text) && fileInfo.Directory != null && fileInfo.Directory.Exists;
        }

        private void backupBrowse_Click(object sender, EventArgs e) {
            if (saveFileDialog.ShowDialog() == DialogResult.OK) {
                backupFileName.Text = saveFileDialog.FileName;
            }
        }
    }
}